package com.cloudinnov.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

import com.cloudinnov.logic.CarDetectorLogic;
import com.cloudinnov.model.CarDetectorData;
import com.cloudinnov.utils.support.spring.SpringUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class CarDetectorServerWP {

	static final Logger LOG = Logger.getLogger(CarDetectorServerWP.class);
	public static final String TOTAL_CAR = "total:car";
	public static final String CAL_NAME = "car:deviceId:";
	public static final String CAL_VALUE = ":value";
	private static final int RECENT_LIST_COUNT = 10000;
	public static final String SPLITTER_LEVEL0 = ",";
	private CarDetectorLogic carDetectorLogic = SpringUtils.getBean("carDetectorLogic");
	private JedisPool jedisPool = SpringUtils.getBean("jedisPool");

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static boolean isConnect = false;
	private static Socket socket;
	private static String ip;
	private static int port;

	public CarDetectorServerWP(String ip, int port) {
		// TODO Auto-generated constructor stub
		this.ip = ip;
		this.port = port;
	}

	public void startConnectService() {

		try {
			socket = new Socket(ip, port);
			isConnect = true;

		} catch (Exception e) {
			// TODO: handle exception
			isConnect = false;
		}
		if (isConnect) {
			// new ThreadWriter(socket).start();
			new ThreadReader(socket).start();
			LOG.info("重新建立 连接成功");
		} else {
			connectAgain();
		}
	}

	private void connectAgain() {
		try {
			socket = new Socket(ip, port);
			isConnect = true;

		} catch (Exception e) {
			// TODO: handle exception
			isConnect = false;
		}
		if (isConnect) {
			// new ThreadWriter(socket).start();
			new ThreadReader(socket).start();
			LOG.info("重新建立连接成功");
		} else {
			connectAgain();
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private class ThreadReader extends Thread {
		Socket socket;

		public ThreadReader(Socket socket) {
			this.socket = socket;
			this.setName("ThreadReader");
		}

		@Override
		public void run() {
			try {
				while (true) {
					InputStream is = socket.getInputStream();
					BufferedReader reader = new BufferedReader(new InputStreamReader(is));
					String s = reader.readLine();

					if (s.length() > 10) {
						parseCarData(s);
					}
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				 LOG.error("正在尝试重新建立连接");
				connectAgain();
			}

		}
	}

	private class ThreadWriter extends Thread {
		Socket socket;

		public ThreadWriter(Socket socket) {
			this.socket = socket;
			this.setName("ThreadWriter");
		}

		@Override
		public void run() {
			try {
				while (true) {
					socket.sendUrgentData(0xff);
					Thread.sleep(2000);
				}

			} catch (Exception e) {
				// TODO Auto-generated catch block
				System.err.println("网络断线");
			}
		}
	}

	private void parseCarData(String result) {

		try {
			String keyRealtime, totalName, value;
			Jedis redis = jedisPool.getResource();
			CarDetectorData model = new CarDetectorData();
			model.setUtcTime(new Date());
			model.setTimeMillis(System.currentTimeMillis());
			String[] dataArr = result.split(",");

			model.setDeviceId(dataArr[0]);

			model.setPeriod(Integer.parseInt(dataArr[1]));

			String recoderId = dataArr[2];

			String year = "20" + dataArr[3].substring(0, 2);
			String month = dataArr[3].substring(2, 4);
			String day = dataArr[3].substring(4, 6);
			String hour = dataArr[3].substring(7, 9);
			String minite = dataArr[3].substring(9, 11);
			String second = dataArr[3].substring(11, 13);
			String date = year + "-" + month + "-" + day + " " + hour + ":" + minite + ":" + second;
			Date dataDate = sdf.parse(date);
			model.setSummaryTime(date);

			model.setFirstLaneOneKind(Integer.parseInt(dataArr[4]));
			model.setFirstLaneOneKindAvg((int)(Double.parseDouble(dataArr[5])));
			model.setFirstLaneTwoKind(Integer.parseInt(dataArr[6]));
			model.setFirstLaneTwoKindAvg((int)(Double.parseDouble(dataArr[7])));
			model.setFirstLaneThreeKind(Integer.parseInt(dataArr[8]));
			model.setFirstLaneThreeKindAvg((int)(Double.parseDouble(dataArr[9])));
			model.setFirstLaneFourKind(Integer.parseInt(dataArr[10]));
			model.setFirstLaneFourKindAvg((int)(Double.parseDouble(dataArr[11])));
			model.setFirstLaneFlow(model.getFirstLaneOneKind()+model.getFirstLaneTwoKind()+model.getFirstLaneThreeKind()+model.getFirstLaneFourKind());
			model.setSecondLaneOneKind(Integer.parseInt(dataArr[12]));
			model.setSecondLaneOneKindAvg((int)(Double.parseDouble(dataArr[13])));
			model.setSecondLaneTwoKind(Integer.parseInt(dataArr[14]));
			model.setSecondLaneTwoKindAvg((int)(Double.parseDouble(dataArr[15])));
			model.setSecondLaneThreeKind(Integer.parseInt(dataArr[16]));
			model.setSecondLaneThreeKindAvg((int)(Double.parseDouble(dataArr[17])));
			model.setSecondLaneFourKind(Integer.parseInt(dataArr[18]));
			model.setSecondLaneFourKindAvg((int)(Double.parseDouble(dataArr[19])));
			model.setSecondLaneFlow(model.getSecondLaneOneKind()+model.getSecondLaneThreeKind()+model.getSecondLaneTwoKind()+model.getSecondLaneFourKind());
			model.setThirdLaneOneKind(Integer.parseInt(dataArr[20]));  
			model.setThirdLaneOneKindAvg((int)(Double.parseDouble(dataArr[21])));
			model.setThirdLaneTwoKind(Integer.parseInt(dataArr[22]));
			model.setThirdLaneTwoKindAvg((int)(Double.parseDouble(dataArr[23])));
			model.setThirdLaneThreeKind(Integer.parseInt(dataArr[24]));
			model.setThirdLaneThreeKindAvg((int)(Double.parseDouble(dataArr[25])));
			model.setThirdLaneFourKind(Integer.parseInt(dataArr[26]));
			model.setThirdLaneFourKindAvg((int)(Double.parseDouble(dataArr[27])));
			model.setThirdLaneFlow(model.getThirdLaneOneKind()+model.getThirdLaneTwoKind()+model.getThirdLaneThreeKind()+model.getThirdLaneFourKind());
			model.setForthLaneOneKind(Integer.parseInt(dataArr[28]));
			model.setForthLaneOneKindAvg((int)(Double.parseDouble(dataArr[29])));
			model.setForthLaneTwoKind(Integer.parseInt(dataArr[30]));
			model.setForthLaneTwoKindAvg((int)(Double.parseDouble(dataArr[31])));
			model.setForthLaneThreeKind(Integer.parseInt(dataArr[32]));
			model.setForthLaneThreeKindAvg((int)(Double.parseDouble(dataArr[33])));
			model.setForthLaneFourKind(Integer.parseInt(dataArr[34]));
			model.setForthLaneFourKindAvg((int)(Double.parseDouble(dataArr[35])));
			model.setForthLaneFlow(model.getForthLaneOneKind()+model.getForthLaneTwoKind()+model.getForthLaneThreeKind()+model.getForthLaneFourKind());
			model.setFirstLaneOccuPancy(Integer.parseInt(dataArr[36]));
			model.setSecondLaneOccuPancy(Integer.parseInt(dataArr[37]));
			model.setThirdLaneOccuPancy(Integer.parseInt(dataArr[38]));
			model.setForthLaneOccuPancy(Integer.parseInt(dataArr[39].split("#")[0]));
			long allCar=model.getFirstLaneFlow()+model.getSecondLaneFlow()+model.getThirdLaneFlow()+model.getForthLaneFlow();
			model.setCarTotal(allCar);
			keyRealtime = CAL_NAME + model.getDeviceId() + CAL_VALUE;
			totalName = TOTAL_CAR + CAL_VALUE;
			value = model.getCarTotal() + SPLITTER_LEVEL0 + model.getTimeMillis()  ;
			redis.lpush(keyRealtime, value);// 单个车检仪器只保存最新的3000条数据
			redis.ltrim(keyRealtime, 0L, RECENT_LIST_COUNT);
			redis.set(totalName, value);// 总数只保留最新的一条
			LOG.debug("keyRealtime:\t:" + keyRealtime + "\tvalue：\t" + value);

			MultiThreadServer.carDetectorLogic.saveRealTimeDataToMongoDB(model);
			
		} catch (Exception e) {
			LOG.error("数据解析失败"+e.toString());
		}
	}
}
